﻿using AvalSqlIndexManager.Models;
using ReactiveUI;
using System;
using System.Reactive.Linq;
using System.Linq;
using System.Windows.Input;
using System.Collections.ObjectModel;
using AvaloniaEdit.Document;
using System.Text;

namespace AvalSqlIndexManager.ViewModels;

public class MainViewModel : ViewModelBase
{
    public ObservableCollection<NodeViewModel> Nodes { get; }

    NodeViewModel? _selectedNode;
    public NodeViewModel? SelectedNode
    {
        get => _selectedNode;
        set { this.RaiseAndSetIfChanged(ref _selectedNode, value); }
    }

    private string? _sqlIndex;

    public string? SqlIndex
    {
        get { return _sqlIndex; }
        set { this.RaiseAndSetIfChanged(ref _sqlIndex, value); }
    }
    private TextDocument _textDocument;
    public TextDocument TextDocument
    {
        get => _textDocument;
        set { this.RaiseAndSetIfChanged(ref _textDocument, value); }
    }
    public ICommand EditIndexCommond { get; }

    public ICommand NewIndexCommond { get; }

    public Interaction<IndexEditViewModel, TableIndex?> ShowDialog { get; }

    private TableStorage storage;

    public MainViewModel() {
        this._textDocument = new TextDocument();
        this.WhenAnyValue(x => x.SelectedNode)
               .Throttle(TimeSpan.FromMilliseconds(400))
               .ObserveOn(RxApp.MainThreadScheduler)
               .Subscribe(buildSqlIndex!);

        storage = TableStorage.FromFile();

        Nodes = storage.TableNodes;
        
        ShowDialog = new Interaction<IndexEditViewModel, TableIndex?>();
        EditIndexCommond = ReactiveCommand.CreateFromTask(async () =>
        {
            var store = new IndexEditViewModel();
            if (this.SelectedNode == null||this.SelectedNode.TableIndex==null)
                return;
            store.EditingNode = this.SelectedNode.TableIndex;
            var result = await ShowDialog.Handle(store);
            if (result != null)
            {
                this.SelectedNode.Title = result.FieldsName;
                storage.Save();
            }
        });

        NewIndexCommond = ReactiveCommand.CreateFromTask(async () =>
        {
            var store = new IndexEditViewModel();
            store.EditingNode = new TableIndex();
            var result = await ShowDialog.Handle(store);
            if (result != null)
            {
                //Nodes.Add(result);
                if (result != null)
                {
                    storage.AddIndex(result);
                    storage.Save();
                }
            }
        });
    }

    private void buildSqlIndex(object s)
    {
        if (this.SelectedNode != null)
        {
            if (this.SelectedNode.TableIndex != null)
                this.TextDocument.Text = this.SelectedNode.TableIndex.BuildCreateSql();
            if(this.SelectedNode.SubNodes != null)
                this.TextDocument.Text = buildChildsIndexSql(this.SelectedNode.SubNodes);
        }
    }

    private string buildChildsIndexSql(ObservableCollection<NodeViewModel> subNodes)
    {
        StringBuilder builder = new StringBuilder();
        foreach (NodeViewModel node in subNodes)
        {
            if (node.TableIndex != null)
            {
                builder.Append(node.TableIndex.BuildCreateSql());
                builder.Append("\r\n");
            }
        }
        return builder.ToString();
    }
}
